grammar dp2;

options {
    language  = Java; 
                     
}

@header {
package group2.grammars;
}

@lexer::header {
	package group2.grammars;
}

prog: rule+;	

rulebase:
     (fact | rule | suprel | conf )* 
     
     ;
     //Definition of Facts
fact:
    fid COLON literal PERIOD
    {System.out.println("Fact: " + $fact.text + "\n");}		
    ;
    
literal:
       TILDE? atom
       {System.out.println("Literal: " + $literal.text + "\n");}		
       ;
       
atom:
     pred LPAREN expr RPAREN
     {System.out.println("Atom: " + $atom.text + "\n");}	
     //pred LPAREN slot(SEMI slot)* RPAREN
     //| rid COLON pred LPAREN rid COLON slot(SEMI slot)* RPAREN 
     //pred LPAREN slot((SEMI) slot)* RPAREN
     ;
     
expr:
    slot(SEMI slot)*
    {System.out.println("Expression: " + $expr.text + "\n");}		
    ;
     
slot:
     sname ARROW svalue
     | sname COLON sname ARROW svalue
     {System.out.println("Slot: " + $slot.text + "\n");}	
     //| sname ARROW? svalue
     //| sname COLON var
      ;	

//Definition of Rules
rule:	
    rid COLON head imp body? PERIOD
    {System.out.println($rid.text + ":" + $head.text + $imp.text + $body.text + "." + "\n");} 
    //| NEWLINE	
    ;
    
rid:
   symbol	
   {System.out.println("Rule ID: " + $symbol.text + "\n");}	
   ;
   
head:
     literal
     {System.out.println("Literal: " + $literal.text + "\n");}	
;

imp:
    IMP | EQIMP| TILIMP	
;

body:	
    cond_cluster((COMMA cond_cluster)|(COMMA naf_cluster))*
    {System.out.println("Body: " + $body.text + "\n");}	
;

cond_cluster:	
            literal((COMMA literal)|(COMMA cond))*
            {System.out.println("Condition Cluster: " + $cond_cluster.text + "\n");}	
	    ;
	
naf_cluster:	
           BSLASH PLUS cond_cluster
           {System.out.println("NAF Cluster: " + $naf_cluster.text + "\n");}	
	   ;


cond:	
    unkeyed extfunc unkeyed
    {System.out.println("Condition: " + $cond.text + "\n");}	
    ;

unkeyed:
       ind | var 	
	;
	
extfunc:
       symbol	
       ;
	
pred:
    symbol
    | symbol COLON symbol
    {System.out.println("Predicate: " + $pred.text + "\n");}		
;
	
svalue:	
      ind | var
      {System.out.println("SValue: " + $svalue.text + "\n");}	
      ;

sname:
     symbol
     {System.out.println("SName " + $sname.text + "\n");}	
     //symbol COLON symbol	
;
    
    
fid:
   symbol
   {System.out.println("Fact ID: " + $fid.text + "\n");}		
   ;	

ind:	
    symbol
    ;
	

    
suprel:	
      rid GT rid PERIOD
      {System.out.println("Super Relation: " + $suprel.text + "\n");}		
      ;

conf:	
    (IMP | EQIMP)literal(COMMA literal)+(var BKIMP var)+ PERIOD	
    {System.out.println("conf: " + $conf.text + "\n");}	
    ;
    
var:
    QMARK symbol
    {System.out.println("Variable: " + $var.text + "\n");}	
    ;   
   
symbol:
      SYMBOL 
      | QSYMBOL
      ;
    
GT:	'>';   
PIPE:	'|'{System.out.println("|");};
BANG:	'!'{System.out.println("!");};
HAT:	'^'{System.out.println("^");};
COLON:	':'{System.out.println(":");};
SEMI:	';'{System.out.println(";");};
LBRACK: '['{System.out.println("[");};
RBRACK: ']'{System.out.println("]");};
LPAREN: '('{System.out.println("(");};
RPAREN: ')'{System.out.println(")");};
QMARK: '?'{System.out.println("?");};
COMMA: ','{System.out.println(",");};
PERIOD: '.' {System.out.println(".");};
LBRACE: '{'{System.out.println("{");};
RBRACE: '}'{System.out.println("}");};
USCORE: '_'{System.out.println("_");};
TILDE:	'~'{System.out.println("~");};
PLUS:	'+'{System.out.println("+");};
BSLASH: '\\'{System.out.println("\\");};
HATHAT:	'^^'{System.out.println("^^");};
//BKSLASH: '\"';
ARROW: '->';
IMP: ':-'{System.out.println(":-");};
EQIMP: ':='{System.out.println(":=");};
TILIMP:	':~'{System.out.println(":~");};
BKIMP:	'\=';

URI:	'<' ('a'..'z'|'A'..'Z'|'0'..'9'|'_'|':'|'/'|'.'|'?'|'&'|'%'|'#'|'-')+ '>';
SYMBOL:  
('-')? ('a'..'z'|'A'..'Z'|'0'..'9'|'$') ('a'..'z'|'A'..'Z'|'0'..'9'|'_'|'.'|'$')*; 
//('a'..'z'|'A'..'Z')+('a'..'z'|'A'..'Z'|'0'..'9')*;
//INT 	:'0'..'9'+ ;
QSYMBOL: '\"' (~('\"'))* '\"';

COMMENT:
    '%' (~('\n'))* { skip(); };
// Single-line comments are denoted by % - the remainder of the line is ignored

MLCOMMENT:
    '/%' (~('%'))* '%/' { skip(); };
// Multi line comments are denoted by /% .... %/ - the comment body cannot contain the % character

NEWLINE: '\r'? '\n' ;

WS:
	(' ' | '\t') + { skip(); }
	;
// Skip all white space - make sure that newlines are counted properly 
// so that the lines are reported correctly in error messages if needed.